$IDENT PUCOM,05,09, .PSECT .LIST MEB ; ; Copyright (c) 1995-1999 by Mentec Inc., U.S.A. ; All rights reserved ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ONLY ; IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE ; ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT ; BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO ; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND ; SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; ; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS SOFTWARE ; ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL. ; ; ; JASON GALLANT, JOE MELVIN, BOB SCHMEICHEL, SUSAN THOMAS, PAUL WEISS ; ; PREVIOUSLY MODIFIED BY: ; ; G. MARIGOWDA, J. MELVIN, A. HUDED ; T. SCHOELLER ; ; MODIFIED FOR RSX-11M-PLUS V4.5 BY: ; ; D. Carroll 15-Feb-1993 05.08 ; DC113 - Include support for multiple controllers on ; multiple URM's in a multiprocessor environment ; ; D. Carroll 05-Jan-1995 05.09 ; DC310 - Insure that we don't get a controller interrupt ; when going from step 1 to 2 during controller ; initialization at special online time. ; ; ; THIS MODULE CONTAINS ROUTINES AND DATA STRUCTURES REQUIRED TO SUPPORT UQSSP ; PORT PROTOCAL FOR T/MSCP DEVICES. THESE ROUTINES AND DATA STRUCTURES ARE ; USED WITH CLASS DRIVERS IN THE SYSTEM TO PROVIDE SUPPORT FOR SUCH DEVICES. ;============================================================================ ; PLEASE NOTE THE FOLLOWING RESTRICTIONS WHEN MODIFYING THIS MODULE ; ; - THE JUMP TABLE DEFINED AT LABEL UQBEGN -MUST- APPEAR AT RELATIVE OFFSET 0. ; ; - PUCOM IS CURRENTLY SET UP TO ONLY HANDLE VIRTUAL CIRCUIT ID OF 0 OR 1. ;============================================================================ .MCALL HWDDF$,UCBDF$,SCBDF$,UDADF$,KRBDF$ HWDDF$ ; HARDWARE REGISTERS UCBDF$ ; UNIT CONTROL BLOCK OFFSETS UDADF$ ; T/MSCP SYMBOLS AND DEFINITIONS SCBDF$ ,,1 ; SCB OFFSETS KRBDF$ ; DEFINE KRB OFFSETS JMPTBL CLASS ; DEFINE CLASS DRIVER JUMP TABLE OFFSETS ; ; LOCAL MACROS ; .MACRO GENLAB PRE,VAL ; GENERATE LABEL PRE'VAL:: .ENDM ;GENLAB .MACRO GENADD PRE,VAL ; GENERATE LABEL, THEN ADDRESS OF IT .WORD PRE'VAL .ENDM ;GENADD .MACRO GETINF TYP,CON ; GENERATE SYMBOL, SAVE NUMBER OF RINGS RNUM=TYP'$R'CON CNUM=TYP'$C'CON .ENDM ;GETINF .MACRO GENTAB BASE,CON,LEN,NUM,PTYPE ADDR=BASE'CON .REPT NUM .WORD ADDR + ENVLEN ; ADDRESS OF PTYPE PKT ADDR=ADDR + LEN + ENVLEN .ENDR .ENDM ;GENTAB .MACRO RECORD DDD,CON .WORD DDD'QST'CON .ENDM ;RECORD .MACRO INDEX PRE,VAL ; GENERATE SUBTITLE ASSEMBLER DIRECTIVE .SBTTL . PRE: DATA STRUCTURES FOR CONTROLLER VAL .ENDM ;INDEX ; ; EQUATED SYMBOLS ; IP = 0 ; IP OFFSET IN CSR SA = 2 ; SA OFFSET IN CSR ERROR = 100000 ; CONTROLLER ERROR INDICATOR STEP4 = 40000 ; STEP 4 BIT STEP3 = 20000 ; STEP 3 BIT STEP2 = 10000 ; STEP 2 BIT STEP1 = 4000 ; STEP 1 BIT NOVEC = 2000 ; CANNOT USE HARDWIRED VECTOR QB = 1000 ; 22 BIT BUS SUPPORTED INTE = 200 ; INTERRUPT ENABLE LF = 2 ; 'SEND LAST FAILURE PACKET' FLAG GO = 1 ; GO BIT .PAGE .SBTTL JMPTAB - JUMP TABLE OF VARIOUS PORT ROUTINES ;============================================================================= ; THE FOLLOWING JUMP TABLE --- MUST --- BE DEFINED FIRST! CLASS DRIVERS EXPECT ; TO SEE THIS TABLE AT 140000 (TO BE MAPPED INTO APR 6 OF CLASS DRIVER) ; ; THIS TABLE USES SYMBOLS FROM IN DSAPRE.MAC. BE CAREFUL WHEN ADDING ROUTINES. ;============================================================================= UQBEGN::.WORD MAJOR*256.+MINOR ; COMPONENT ID (SET UP IN $IDENT MACRO) .WORD PORSUP ; PORT SETUP .WORD PORINT ; CONTROLLER INTERRUPT HANDLER .WORD PORSEN ; SEND COMMAND PACKET TO CONTROLLER .WORD PORUMR ; ALLOCATE / DEALLOCATE UMRS .WORD PKTAC ; ALLOCATE COMMAND PACKET .WORD PKTDR ; DEALLOCATE RESPONSE PACKET .WORD PKTCHK ; CHECK FOR RESOURCES .WORD STOMP ; RESET THE CONTROLLER CONCNT: .WORD 0 ; # OF CONTROLLERS CONNECTED TO PORT .WORD PKTCH1 ; CHECK FOR RESOURCES - IMMEDIATE CMDS .WORD PORSYN ; PORT SYNCHRONIZATION .WORD 0 ; EXEC VECTORING FROM APR6 CODE ROUTINE ; FILLED IN BY CLASS DRIVER .WORD -1 ; TABLE TERMINATOR TABTAB:: ; TABLE OF QST TABLE ADDRESSES .IRP CON, .WORD CON'QTBL ; ADDRESS OF TABLE OF ADDRESSES .ENDM ;CON .WORD -1 ; TABLE TERMINATOR LOGDAT ; DATA CELLS FOR DEBUG TRACE UMRMAP: .BLKW 1 ; ADDRESS OF MAPPING BLOCK OF UMR .IF DF,M$$PRO .BLKW M$$PRO-1 ; Static mapping/CPU CPUCNT: .BLKB M$$PRO ; Count of controllers connected / CPU .EVEN UMRPT: .BLKW 1 ; pointer into UMRMAP .ENDC ;DF,M$$PRO UQRELC: .BLKW 2 ; RELOCATION CONSTANT USED TO CONVERT .IF DF,M$$PRO ; VIRTUAL TO PHYSICAL ADDRESSES .BLKW <*2> ; for each CPU .ENDC ;DF,M$$PRO ; EXEVEC: .WORD 0 ; EXECUTIVE VECTOR FLAG ALOCB: .WORD $ALOCB ASUMR: .WORD $ASUMR DEACB: .WORD $DEACB DEUMR: .WORD $DEUMR DEVHD: .WORD $DEVHD ; USED BY TRACE CODE HFMSK: .WORD $HFMSK KISR6: .WORD KISAR6 MPUB1: .WORD $MPUB1 .IF DF,M$$PRO PROC2: .WORD $PROC2 PROCN: .WORD $PROCN .ENDC ;DF,M$$PRO EXEVCL=<<<.-EXEVEC>/2>-1> ; TABLE LENGTH FOR VECTORING .PAGE .SBTTL TABLES - DATA STRUCTURES FOR DISK/TAPE CLASS MSCP ;=============================================================================== ; SET UP DATA STRUCTURES FOR ALL CLASS DRIVERS ;=============================================================================== .IRP DEV, ; ASSUME SAME TABLE STRUCTURE FOR EACH CONT=0 ; INITIAL CONTROLLER NUMBER .IF IDN .IIF NDF R$$UDA R$$UDA=0 LOOP = R$$UDA ; USE NUMBER OF MSCP CONTROLLERS .ENDC .IF IDN .IIF NDF R$$MYA R$$MYA = 0 LOOP = R$$MYA ; USE NUMBER OF TMSCP CONTROLLERS .ENDC .REPT LOOP ; FOR EACH MSCP CONTROLLER INDEX DEV,\CONT ; GENERATE SUBTITLE GETINF DEV,\CONT ; # OF CMD/RSP RINGS FOR CONTROLLER .PAGE ; ------------------------------- ; SET UP THE CST FOR CONTROLLER ; ------------------------------- GENLAB DEV'CST,\CONT ; LABEL .WORD 0 ; C.STAT - CONNECTION STATE STATUS .WORD 0 ; C.EXTN - RESERVED. DO NOT MOVE/DELETE .WORD 0,0 ; C.CMST - OLDEST OUTSTANDING CMD .WORD 0,.-2 ; C.OLHD - OUTSTANDING I/O LIST HEAD .WORD 0 ; C.CMDS - CREDIT COUNT FOR CONTR .BYTE 0 ; C.VCID - VIRTUAL CIRCUIT ID .BYTE 0 ; C.FLAG - CLASS DRIVER CONTROL FLAG .WORD 0 ; C.REDO - COMMAND TO BE REISSUED .WORD 0 ; C.REQU - QUEUE OF CMDS TO RESTART .WORD .-2 ; AFTER RESYNCH .IF DF E$$LOG .WORD 0 ; C.MLNG - LENGTH OF CONTROLLER ERROR .BYTE 0 ; C.CRED - CREDIT/DEBIT COUNT .BYTE 0 ; C.VCIX - VIRTUAL CIRCUIT ID .WORD 0 ; C.IP - SAVED IP REGISTER .WORD 0 ; C.SA - SAVED SA REGISTER .ENDC ;E$$LOG .IF DF M$$EXT .WORD MAXWBT ; C.UMCT - # OF UMR WAIT BLOCKS AVAIL .REPT MAXWBT ; C.UMRW - TABLE OF UMR WAIT BLOCK .WORD 0 ; ADDRESSES .ENDR .ENDC ;M$$EXT ; --------------------------------- ; SET UP THE QST FOR THE CONTROLLER ; --------------------------------- GENLAB DEV'QST,\CONT ; LABEL GENADD DEV'CST,\CONT ; Q.CST - PNTR TO ASSOCIATE CST .WORD 0 ; Q.STAT - STATUS BITS (PORT-CONTROLLER) .WORD 0 ; Q.SAD - INTERRUPT HANDLER (DYNAMIC) .BYTE 0 ; RESERVED FOR DIGITAL USE .BYTE 0 ; Q.INF - CONTROLLER INFORMATION .BYTE RNUM ; Q.RSPN - NUMBER OF RESPONSE RINGS .BYTE CNUM ; Q.CMDN - NUMBER OF COMMAND RINGS .BYTE 0 ; Q.CTM - CURRENT TIME OUT COUNT .BYTE 0 ; Q.RTY - CURRENT RETRY COUNT ; Q.RING - START OF RING AREA. MUST ; BE SAME ADDRESS AS Q.FRSP! GENADD DEV'FRR,\CONT ; Q.FRSP - PNTR TO FIRST RESPONSE RING GENADD DEV'LRR,\CONT ; Q.LRSP - PNTR TO LAST RESPONSE RING GENADD DEV'FCR,\CONT ; Q.FCMD - FIRST COMMAND RING GENADD DEV'LCR,\CONT ; Q.LCMD - LAST COMMAND RING GENADD DEV'RPT,\CONT ; Q.RPAT - PNTR TO RSP PACKET ADDRESSES GENADD DEV'CPT,\CONT ; Q.CPAT - PNTR TO CMD PACKET ADDRESSES .WORD 0 ; Q.CRSP - CURRENT RESPONSE RING WHEN ; CONTROLLER ONLINE (MSCP) ; Q.STEP - SYNC STEP BIT WHEN CONTROLLER ; IS SYNCRONIZING. THIS FIELD ; DELIBERATELY OVERLAPS Q.CRSP .WORD 0 ; Q.CCMD - CURRENT COMMAND RING WHEN ; CONTROLLER IS ONLINE (MSCP) ; Q.INDX - SYNC STEP INDEX WHEN CNTRL ; SYNCHRONIZING. DELIBERATELY ; OVERLAPS Q.CCMD. .WORD 0,0,0,0 ; Q.WRIT - WORDS TO WRITE TO SA IN SYNC .WORD 0 ; Q.TEMP - CONTR SPECIFIC WORK AREA .BYTE 0 ; Q.IOSQ - CONTROLLER SEQUENCE .BYTE 0 ; RESERVED FOR DIGITAL USE .WORD 0,0,0,0 ; Q.CNTI - CNTRL T/MSCP ID ; Q.ID <-- Q.CNTI+6 .BYTE 0 ; Q.CSVR - CNTRL SOFT VERSION .BYTE 0 ; Q.CHVR - CNTRL HARD VERSION ; --------------------------------------------- ; ALLOCATE SPACE FOR CMD/RSP TABLE OF ADDRESSES ; --------------------------------------------- GENLAB DEV'RPT,\CONT ; TABLE OF RSP PKT ADDR GENTAB DEV'DRP,\CONT,RPLEN,RNUM,RSP ; GEN TABLE OF ADDRESSES GENLAB DEV'CPT,\CONT ; TABLE OF CMD PKT ADDR GENTAB DEV'DCP,\CONT,CPLEN,CNUM,CMD ; GEN TABLE OF ADDRESSES ; ------------------------------------------------- ; ALLOCATE THE SPACE FOR THE RESPONSE/COMMAND RINGS ; ------------------------------------------------- .WORD 0 ; CONTROLLER COMMAND INTERRUPT ADDR .WORD 0 ; CONTROLLER RESPONSE INTERRUPT ADDR GENLAB DEV'FRR,\CONT ; FIRST RESPONSE RING BEGINS HERE .REPT ; 2 WORDS EACH; N-1 RESPONSE RINGS .WORD 0,0 .ENDR GENLAB DEV'LRR,\CONT ; LAST RESPONSE RING BEGINS HERE .WORD 0,0 ; LAST RESPONSE RING GENLAB DEV'FCR,\CONT ; FIRST COMMAND RING BEGINS HERE .REPT ; 2 WORDS EACH; N-1 COMMAND RINGS .WORD 0,0 .ENDR GENLAB DEV'LCR,\CONT ; LAST COMMAND RING BEGINS HERE .WORD 0,0 ; LAST COMMAND RING ; --------------------------------- ; ALLOCATE COMMAND/RESPONSE PACKETS ; --------------------------------- GENLAB DEV'DRP,\CONT ; LABEL .REPT RNUM .WORD RPLEN ; INSURE MAX PACKET SIZE ON INITIAL CALL .WORD 0 ; SECOND ENVELOP WORD .BLKB RPLEN ; ALLOCATE RESPONSE PACKET .ENDR ; FOR EACH RESPONSE RING GENLAB DEV'DCP,\CONT ; LABEL .REPT CNUM .WORD CPLEN ; INSURE MAX PACKET SIZE ON INITIAL CALL .WORD 0 ; SECOND ENVELOP WORD .BLKB CPLEN ; ALLOCATE COMMAND PACKET .ENDR ; FOR EACH COMMAND RING CONT=CONT + 1 ; NEXT CONTROLLER .ENDR ;LOOP ; ; GENERATE TABLE WITH THE ADDRESSES OF THE QSTS FOR THIS CLASS ; .WORD LOOP ; RECORD NUMBER OF CONTROLLERS DEV'QTBL:: CONT=0 .REPT LOOP RECORD DEV,\CONT CONT=CONT + 1 .ENDR ;LOOP .ENDM ;IRP CODBEG = . .PAGE .SBTTL PKTAC - ALLOCATE COMMAND PACKET ;+ ; **-PKTAC-ALLOCATE COMMAND PACKET ; ; THIS ROUTINE CALCULATES THE ADDRESS OF THE AVAILABLE COMMAND PACKET, GIVEN ; THE COMMAND DESCRIPTOR ADDRESS. THE PKTCHK ROUTINE HAS ALREADY BEEN CALLED. ; ; INPUTS: ; ; R0 = NUMBER OF WORDS TO ALLOCATE FOR THE TEXT PORTION OF PACKET ; R2 = QST ADDRESS ; R3 = IOP ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R0 = DESTROYED ; R1 = VIRTUAL ADDRESS OF COMMAND PACKET TO USE (TEXT PORTION) ; R2-R5 = PRESERVED ;- PKTAC:: MOV Q.CCMD(R2),R1 ; ADDR OF CMD RING DESCR TO ALLOCATE SUB Q.FCMD(R2),R1 ; THE BEGINNING OF THE CMD RING DESCR ASR R1 ; DIVIDE BY TWO ADD Q.CPAT(R2),R1 ; BASE ADDR TO THE OFFSET MOV (R1),R1 ; ACTUAL PACKET ADDRESS MOV R0,MSGLNG(R1) ; STORE IN ENVELOP ASL MSGLNG(R1) ; MAKE IT BYTE VALUE PUSH ; SAVE THE PACKET ADDRESS 10$: CLR (R1)+ ; ZERO OUT WORD OF PACKET SOB R0,10$ ; CLEAR OUT THE WHOLE PACKET POP ; GET PACKET ADDRESS RETURN ; AND RETURN TO CALLER .PAGE .SBTTL PKTCHK - CHECK FOR REQUIRED RESOURCES: NON-IMMEDIATE CMDS .SBTTL PKTCH1 - CHECK FOR REQUIRED RESOURCES: IMMEDIATE CMDS ;+ ; **-PKTCHK-CHECK FOR RESOURCES BEFORE ISSUING I/O - NON-IMMEDIATE CMDS ; **-PKTCH1-CHECK FOR RESOURCES BEFORE ISSUING I/O - IMMEDIATE CMDS ; ; PKTCHK CHECKS FOR SUFFICIENT RESOURCES TO ISSUE A NON-IMMEDIATE COMMAND. ; SUCCESS IS RETURN IF THERE ARE SUFFICIENT CREDITS (AT LEAST TWO) TO ISSUE ; THE COMMAND .AND. THERE IS AT LEAST ONE HOST OWNED COMMAND RING. ; ; PKTCH1 CHECKS FOR SUFFICIENT RESOURCES TO ISSUE AN IMMEDIATE COMMAND. ; SUCCESS IS RETURN IF THERE ARE SUFFICIENT CREDITS (AT LEAST ONE) TO ISSUE ; THE COMMAND .AND. THERE IS AT LEAST ONE HOST OWNED COMMAND RING. ; ; INPUTS: ; ; R2 = QST ADDRESS ; ; OUTPUTS: ; ; R0 = PRESERVED ; R1 = DESTROYED ; R2-R5 = PRESERVED ; C - 0 = RESOURCES AVAILABLE. Q.CCMD(R2) IS ADDRESS OF COMMAND RING ; C - 1 = NO RESOURCES AVAILABLE. Q.CCMD NOT MODIFIED ; .ENABL LSB PKTCHK:: ASSUME Q.CST,0 MOV (R2),R1 ; GET CST CMP C.CMDS(R1),#1 ; AT LEAST 2 CREDITS? BLE 100$ ; NO. RETURN FAILURE MOV Q.CCMD(R2),R1 ; CHECK CURRENT CMD DESCRIPTOR TST MSW(R1) ; HOST OWNED? BLT 90$ ; NO. RETURN FAILURE CLC ; INDICATE SUCCESS RETURN PKTCH1:: ASSUME Q.CST,0 MOV (R2),R1 ; GET CST TST C.CMDS(R1) ; AT LEAST ONE CREDIT? BLE 100$ ; NO. RETURN FAILURE MOV Q.CCMD(R2),R1 ; CHECK CURRENT CMD DESCRIPTOR TST MSW(R1) ; HOST OWNED? BLT 90$ ; NO. RETURN FAILURE CLC ; INDICATE SUCCESS RETURN 90$: 100$: SEC ; INDICATE FAILURE RETURN .DSABL LSB .PAGE .SBTTL PKTDR - DEALLOCATE RESPONSE PACKET ;+ ; **-PKTDR-DEALLOCATE RESPONSE PACKET ; ; THIS ROUTINE DEALLOCATES THE DESIGNATED RESPONSE PACKET. THIS INVOLVES FINDING ; THE CORRESPONDING RESPONSE RING DESCRIPTOR AND MARKING IT AS CONTROLLER OWNED. ; ; INPUTS: ; ; R1 = RESPONSE PACKET ADDRESS ; R2 = QST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R1-R5 = PRESERVED ;- PKTDR:: MOV #RPLEN,MSGLNG(R1) ; RESTORE MAXIMUM REPONSE PACKET SIZE MOV Q.CRSP(R2),R0 ; GET CURRENT RSP RING DESCR ADDR BIS #OWN,MSW(R0) ; MARK IT AS CONTROLLER OWNED RETURN .PAGE .SBTTL PORINT - CONTROLLER INTERRUPT HANDLER ;+ ; **-PORINT- CONTROLLER INTERRUPT HANDLER ; ; INTERRUPTS ARE RECEIVED FROM CONTROLLER UNDER FOUR CIRCUMSTANCES: ; ; 1. DURING THE INITIALIZATION PROCESS (OPEN THE "VIRTUAL CIRCUIT") ; 2. WHEN "COMMAND RING BUFFER" TRANSITIONS FROM "FULL" TO "NOT FULL" ; 3. WHEN "RESPONSE RING BUFFER" TRANSITIONS FROM "EMPTY" TO "NOT EMPTY" ; 4. WHEN FATAL CONTROLLER ERROR IS DETECTED AND INTERRUPT CAN BE GENERATED. ; ; INPUT: ; ; R5 = UCB ADDRESS ;- PORINT::MOV S.QST(R4),R2 ; GET QST ASSUME Q.CST,0 MOV (R2),R3 ; GET CST MOV S.CSR(R4),R1 ; GET CSR ASSUME C.STAT,0 BIT #C1.FAT,(R3) ; WAITING FOR TIMEOUT TO START RECOVERY? ; CAN SOMETIMES GET INTERRUPT IN MIDDLE ; OF POWERFAIL BEFORE CONTROLLER GETS ; RE-INITIALIZED. BNE 55$ ; YES. GO BACK TST Q.STAT(R2) ; SYNCHRONIZATION STATE? BMI 70$ ; YES. HANDLE SYNCH RELATED INTERRUPTS ; ; THIS SECTION DEALS WITH RESPONSES AND COMMANDS ; 10$: TST SA(R1) ; DID CONTROLLER SUFFER FATAL ERROR? BMI 60$ ; HANDLE CONTROLLER FATAL ERROR 15$: MOV Q.RING(R2),R1 ; GET ADDRESS OF RING AREA CLR CMDINT(R1) ; CLEAR COMMAND INTERRUPT INDICATOR CLR RSPINT(R1) ; AND RESPONSE TOO. ; ; PROCESS ALL RESPONSES ; 20$: MOV Q.CRSP(R2),R1 ; STARTING RESPONSE RING 23$: TST MSW(R1) ; HOST OWNED? BMI 50$ ; NO. SCAN IS DONE SUB Q.FRSP(R2),R1 ; GET OFFSET TO RING FROM BASE ASR R1 ; WORD INDEX ADD Q.RPAT(R2),R1 ; GET TABLE ADDRESS OF ADDRESS MOV (R1),R1 ; GET REAL PACKET ADDRESS LOGRSP ; TRACE RESPONSE PACKETS PUSH ; GET MESSAGE FIELD BIC #^C,(SP) ; MAKE SURE IT IS ONLY MESSAGE TYPE CMP #,(SP) ; MAINTENANCE PACKET? BEQ 25$ ; YES. DO NOT ADD THE CREDITS MOV CREDIT(R1),R0 ; GET CREDIT FIELD BIC #^C,R0 ; MAKE SURE IT IS ONLY CREDIT FIELD ADD R0,C.CMDS(R3) ; ADD TO CLASS CREDIT COUNT 25$: POP ; GET MASKED MESSAGE TYPE BACK BNE 27$ ; MUST NOT BE SEQUENTIAL PACKET ASSUME MSGSEQ,0 ; MAKE THAT ASSUMPTION, THOUGH CALLV CLASS,CLAEND ; PROCESS SEQUENTIAL PACKET ASSUME Q.CST,0 MOV (R2),R3 ; GET CST BR 45$ ; JOIN COMMON CODE 27$: CMPB #,R0 ; DATAGRAM? BNE 40$ ; NO. JUST DEALLOCATE PACKET CALLV CLASS,CLADAT ; PROCESS DATAGRAM BR 45$ ; JOIN COMMON CODE 40$: CALL PKTDR ; THROW PACKET AWAY 45$: MOV Q.CRSP(R2),R1 ; GET CURRENT RING DESCRIPTOR ADDR ADD #CMDSIZ,R1 ; POINT TO NEXT DESCRIPTOR CMP R1,Q.LRSP(R2) ; WRAP AROUND? BLOS 47$ ; NO. MOV Q.FRSP(R2),R1 ; YES. SO WRAP TO BEGINNING 47$: MOV R1,Q.CRSP(R2) ; REMEMBER NEXT ONE TO USE BR 23$ ; GET ANOTHER RESPONSE ; ; ALL RESPONSES HAVE BEEN PROCESSED. TRY TO START MORE I/O ; 50$: JMPV CLASS,CLACMD ; CALL CLASS DRIVER TO START MORE I/O 55$: RETURN ; ; HANDLE CONTROLLER ERROR. ALL ASSOCIATED CLASS DRIVERS WOULD HAVE ; TO BE TOLD AT THIS POINT. ; 60$: SEC ; INDICATE ERROR SHOULD BE LOGGED JMPV CLASS,CLAERR ; INFORM THE CLASS DRIVER(S) ; ; HANDLE SYNCHRONIZATION RELATED INTERRUPTS ; 70$: TST SA(R1) ; WAS THERE FATAL ERROR? BPL 75$ ; NO. CONTINUE JMP OPN ; YES. TRY TO RETRY 75$: TST Q.SAD(R2) ; SPURIOUS INTERRUPT? BMI 77$ ; If MI, go dispatch BNE 55$ ; If NE, already flagged INC Q.SAD(R2) ; flag interrupt received BR 55$ ; and dismiss the interrupt 77$: JMP @Q.SAD(R2) ; No. process required synch step .PAGE .SBTTL PORSEN - SEND COMMAND PACKET TO CONTROLLER ;+ ; **-PORSEN-SEND COMMAND PACKET TO CONTROLLER ; ; THIS ROUTINE SENDS A COMMAND PACKET TO THE CONTROLLER FOR PROCESSING. ONCE ; THE PACKET HAS BEEN SENT, THIS ROUTINE DETERMINES THE NEXT AVAILABLE COMMAND ; RING THAT CAN BE USED. WRAP AROUND PROCESSING TAKES PLACE IN THIS ROUTINE. ; ; INPUTS: ; ; R1 = COMMAND PACKET ADDRESS ; R2 = QST ADDRESS ; R3 = IOP ADDRESS ; R4 = SCB ADDRESS ; R5 = UCR ADDRESS ; ; OUTPUTS: ; ; R1-R5 = PRESERVED ;- ASSUME Q.CST,0 PORSEN::MOV (R2),R0 ; GET CST MOVB C.VCID(R0),VCID(R1) ; SET VIRTUAL CIRCUIT ID DEC C.CMDS(R0) ; DECREMENT CREDIT COUNT MOV Q.CCMD(R2),R0 ; GET CURRENT COMMAND RING BIS #OWN!FLAG,MSW(R0) ; MARK AS CONTR OWNED/REQUEST INTRPTS MOV S.KRB(R4),R0 ; GET KRB MOV K.CSR(R0),R0 ; GET CSR LOGCMD ; TRACE RSX/DSA COMMAND PACKETS ASSUME IP,0 TST (R0) ; START CONTROLLER LOOKING 5$: ADD #CMDSIZ,Q.CCMD(R2) ; POINT TO NEXT RING CMP Q.CCMD(R2),Q.LCMD(R2) ; OUT OF RINGS? BLOS 10$ ; NO. MOV Q.FCMD(R2),Q.CCMD(R2) ; YES. PERFORM WRAP AROUND 10$: RETURN .PAGE .SBTTL PORSUP - SETUP DATA STRUCTURES ETC FOR THE PORT ;+ ; **-PORSUP-PORT SETUP ROUTINE ; ; THIS ROUTINE SETS UP SOME OF THE PRELIMINARY DATA STRUCTURES NEEDED TO ; USE THE DSA DRIVERS. THIS ROUTINE IS RESPONSIBLE FOR PERFORMING THE ; EXECUTIVE VECTORING OF ROUTINES (IF NEEDED) AS WELL AS SETTING UP THE ; CONTROLLER SCB FIELDS WITH THE QST ADDRESS OF THE CONTROLLER. ; ; INPUTS: ; ; R1 = VIRTUAL CIRCUIT ID ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R0 = DESTROYED ; R1 = PRESERVED ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- PORSUP::TST EXEVEC ; ALREADY DONE? BNE 10$ ; YES. MOV @#112,R0 ; GET POINTER TO VECTOR OF POINTERS MOV @(R0),-(SP) ; MAP ROUTINE WITH CORRECT APR BIAS MOV #120000,-(SP) ; GET ADDR. OF TRANSLATE ROUTINE MOV #EXEVCL,R2 ; SPECIFY LENGTH OF VECTOR MOV #EXEVEC,R3 ; POINT TO VECTOR CALL @<140000+MPPRO> ; CALL ROUTINE IN EXEC WHICH MAPS AND ; CALLS TRANSLATE ROUTINE 10$: MOV S.CON(R4),R0 ; GET CONTROLLER INDEX BIC #177400,R0 ; CLEAR HIGH BYTE ASL R1 ; CONVERT VC ID INTO BYTE OFFSET ADD TABTAB(R1),R0 ; GET POINTER TO QST TABLE MOV (R0),R2 ; GET QST ASR R1 ; RESTORE THE VIRTUAL CIRCUIT ID MOV R2,S.QST(R4) ; STORE QST ADDRESS IN SCB ASSUME Q.CST,0 MOV (R2),R3 ; GET CST MOVB R1,C.VCID(R3) ; STORE THE VC ID IN THE CST RETURN .PAGE .SBTTL PORUMR - ALLOCATE/DEALLOCATE STATIC UMR AND DYNAMIC WAIT BLOCKS ;+ ; **-PORUMR-ALLOCATE/DEALLOCATE STATIC UMR AND DYNAMIC WAIT BLOCKS ; ; CALLED WHENEVER CONTROLLER IS BROUGHT ONLINE OR OFFLINE. THE STATIC UMR IS ; ALLOCATED ONLY ONCE, AND COUNT IS KEPT OF HOW MANY CONTROLLERS ARE ONLINE ; TO THE PORT. WHEN THE COUNT GOES TO ZERO, THE UMR IS DEALLOCATED. WAIT ; BLOCKS ARE ALLOCATED ON PER-CONTROLLER BASIS TO AVOID HAVING TO DEAL WITH ; FAIRNESS PROBLEMS. ; ; INPUTS: ; ; C = 1 TRANSITION TO OFFLINE - DEALLOCATE UMR AND WAIT BLOCKS ; R2 = KRB ADDRESS ; ; C = 0 TRANSITION TO ONLINE - ALLOCATE UMR AND WAIT BLOCKS ; R0 = HIGH 6 BITS OF RELOCATION BIAS FOR PORT UMR ; R1 = LOW 16 BITS OF RELOCATION BIAS FOR PORT UMR ; R2 = KRB ADDRESS ; R3 = CST ADDRESS ; ; OUTPUTS: ; ; UMR AND WAIT BLOCKS ALLOCATED OR DEALLOCATED ; FOR THE ONLINE TRANSITION, R0 AND R1 CONTAIN THE RELOCATION BIAS OF THE ; ALLOCATED UMR ;- PORUMR: BCC 30$ ; IF CC ONLINE REQUEST .IF DF,M$$PRO MOVB @PROCN,R0 ; get this processor index DECB CPUCNT(R0) ; drop count of controllers active BNE 10$ ; if NE, not done yet ... ASL R0 ; shift CPU index to index * 2 MOV UMRMAP(R0),R2 ; get the static mapping block address CLR UMRMAP(R0) ; and clear out the assignment .IFF ;DF,M$$PRO TST CONCNT ; LAST CONTROLLER MAPPING THE PORT? BNE 10$ ; NO, JUST DUMP THE WAIT BLOCKS MOV UMRMAP,R2 ; GET ADDRESS OF UMR MAPPING BLOCK CLR UMRMAP ; MAKE SURE UMRMAP=0 SO WE ALLOCATE .ENDC ;DF,M$$PRO ; ..A STATIC UMR AGAIN NEXT TIME PUSH ; SAVE THE CST CALL @DEUMR ; DEALLOCATE STATIC UMR MOV R2,R0 ; GET COPY OF CORE BLOCK ADDRESS MOV #M.LGTH,R1 ; CORE BLOCK LENGTH CALL @DEACB ; DEALLOCATE THE CORE BLOCK POP ; RESTORE THE CST 10$: ADD #C.UMRW,R3 ; POINT TO START OF THE UMR WAIT BLOCK MOV #MAXWBT,-(SP) ; STORE MAX UMR WAIT BLOCKS ON STACK 15$: MOV #UMRWTB,R1 ; SET THE LENGTH OF WAIT BLOCK MOV (R3),R0 ; GET BLOCK BEQ 20$ ; IF EQ WE'RE DONE .IIF DF M$$PRO TST -(R0) ; BACK UP OVER UNIBUS RUN MASK CLR (R3)+ ; CLEAR OUT THE ADDRESS PUSH ; SAVE IT CALL @DEACB ; DEALLOCATE THE CORE BLOCK POP ; AND RESTORE IT DEC (SP) ; KEEP THE COUNT FOR WAIT BLOCKS LEFT BNE 15$ ; GO DO ANOTHER 20$: TST (SP)+ ; CLEAN THE STACK RETURN 30$: .IF DF,M$$PRO MOVB @PROCN,R2 ; get the processor index INCB CPUCNT(R2) ; flag another controller on this CPU ASL R2 ; shift into a word index ADD #UMRMAP,R2 ; convert into an index MOV R2,UMRPT ; and save our pointer TST (R2) ; are we connected? .IFF ;DF,M$$PRO TST UMRMAP ; FIRST CONTROLLER TO CONNECT? .ENDC ;DF,M$$PRO BNE 40$ ; NO, JUST GET WAIT BLOCKS PUSH ; SAVE RELOCATION BIAS HIGH AND LOW MOV #M.LGTH,R1 ; LENGTH OF CORE BLOCK TO ALLOCATE CALL @ALOCB ; ALLOCATE CORE BLOCK BCS 80$ ; ERROR, EXIT .IF DF,M$$PRO MOV R0,@UMRPT ; SAVE THE ADDRESS OF THE CORE BLOCK .IFF ;DF,M$$PRO MOV R0,UMRMAP ; SAVE THE ADDRESS OF THE CORE BLOCK .ENDC ;DF,M$$PRO POP M.BFVL(R0) ; SET UP LO 16-BITS OF ADDRESS MOVB (SP),M.BFVH(R0) ; SET UP HI 6-BITS OF ADDRESS TST (SP)+ ; POP OFF THE WORD TO MAINTAIN THE STACK MOV #4,M.UMRN(R0) ; SET UP COUNT FOR 1 UMR CALL @ASUMR ; GO ASSIGN UMR BCS 90$ ; IF CS, ERROR EXIT ; ; WE'LL DO THE ACTUAL MAPPING LATER SO THAT RESYNCH CAN REMAP ALSO ; ; NOW WE ALLOCATE SET OF UMR WAIT BLOCKS FOR THE CONTROLLER ; 40$: TST C.UMRW(R3) ; ARE WAIT BLOCKS ASSIGNED? BNE 70$ ; IF NE, YES, DONE MOV #DUUMR,R2 ; ASSUME THAT IT IS DISK ASSUME U.DCB,0 MOV (R5),R1 ; GET THE DCB CMP #"DU,D.NAM(R1) ; SEE IF IT IS DISK OR TAPE BEQ 50$ ; IF EQ IT IS DISK MOV #MUUMR,R2 ; IT'S TAPE 50$: PUSH ; SAVE WORKING REGISTERS ADD #C.UMRW,R3 ; POINT TO UMR WAIT QUEUE 60$: MOV #UMRWTB,R1 ; LENGTH OF WORK BLOCK PUSH ; SAVE THE BLOCK INDEX CALL @ALOCB ; ALLOCATE CORE BLOCK FOR UMR ASSIGNMENT POP ; RESTORE THE BLOCK INDEX BCS 65$ ; WE WILL ALLOCATE THE REST DYNAMICALLY .IF DF M$$PRO MOV U.SCB(R5),R4 ; SCB ADDRESS MOV S.URM(R4),(R0)+ ; UNIBUS RUN MASK .ENDC ;M$$PRO MOV R0,(R3)+ ; PUT THE ADDRESS IN THE TABLE SOB R2,60$ ; LOOP THROUGH ALLOCATION 65$: POP ; RESTORE REGISTERS 70$: .IF DF M$$PRO MOV @UMRPT,R0 ; GET THE STATIC UMR WAIT BLOCK .IFF ;DF M$$PRO MOV UMRMAP,R0 ; GET THE STATIC UMR WAIT BLOCK .IFTF ;DF M$$PRO CALL @MPUB1 ; MAP THE UNIBUS .IFT ;DF M$$PRO MOV @UMRPT,R2 ; GET BACK THE STATIC UMR .IFF ;DF M$$PRO MOV UMRMAP,R2 ; GET BACK THE STATIC UMR .ENDC ;DF M$$PRO MOVB M.UMVH(R2),R0 ; HIGH 2 BITS OF RELOCATION BIAS ASH #-4,R0 ; SHIFT BITS 4:5 TO 0:1 MOV M.UMVL(R2),R1 ; LOW 16 BITS OF RELOCATION BIAS CLC ; GOOD RETURN RETURN 80$: POP ; RESTORE REGISTERS 90$: SEC ; ERROR RETURN RETURN .PAGE .SBTTL PORSYN - PORT SYNCHRONIZATION ROUTINE ;+ ; **-PORSYN-STANDARD PORT SYNCHRONIZATION ; ; THIS ROUTINE IS RESPONSIBLE FOR STARTING THE CONTROLLER SYNCHRONIZATION ; PROCESS (WHEN CALLED BY THE CLASS DRIVERS). ; ; INPUTS: ; ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; IF INITIAL PART OF HARDWARE SYNCHRONIZATION BEGINS THEN: ; ; THE CONTROLLER HAS BEGUN STEP 1 OF SYNCHRONIZATION ; R0-R1 = DESTROYED ; R2-R5 = PRESERVED ; ; IF ALL RE-TRIES FAIL: ; ; CONTROL TRANSFERS TO CLASYN ; C=1 TO INDICATE FAILURE ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- PORSYN::MOVB #RETRY,Q.RTY(R2) ; SET UP FOR RETRY RE-TRYS CLR Q.SAD(R2) ; PROTECT AGAINST SPURIOUS INTERRUPT MOV #Q1.SYN,Q.STAT(R2) ; CONTROLLER STATE=SYNCHRONIZING BIS #C1.SYN,(R3) ; SET SYNC STATE MOV #1,C.CMDS(R3) ; SET INTITIAL CREDIT COUNT .PAGE .SBTTL . OPN ;+ ; CONTROL TRANSFERS HERE IF AN ERROR IN SYNCHRONIZATION IS DETECTED. CONTROL ; ALSO FALLS THROUGH TO HERE FROM THE PORSYN ENTRY POINT. ; ; INPUTS: ; ; R0-R1 = MAY BE DESTROYED ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ;- .ENABL LSB OPN:: DECB Q.RTY(R2) ; TRY OR RE-TRY? BGE 5$ ; IF GE, YES MOV #Q1.OFF,Q.STAT(R2) ; CONTROLLER STATE=OFF-LINE ; ; LET CLASS DRIVER HANDLE FAILURE OF SYNCHRONIZATION BY TRANSFERING ; TO CLASYN WITH THE CARRY SET ; BADSYN: SEC ; INDICATE FAILURE TO SYNCHRONIZE JMPV CLASS,CLASYN ; TRANSFER TO CLASS DRIVER (CLASYN) 5$: ; START HARDWARE SYNCHRONIZATION PUSH ; SAVE CST MOV R2,R3 ; GET COPY OF QST ADD #Q.WRIT,R3 ; POINTS TO Q.WRIT TABLE IN QST MOVB S.VCT(R4),(R3) ; (INTERRUPT VECTOR ADDR) / 4 BISB #INTE,(R3)+ ; ENABLE INTERRUPTS ; ; CALCULATE COMMAND RING LENGTH AS POWER OF 2 ; MOVB Q.CMDN(R2),R0 ; GET NUMBER OF CMD DESCRIPTORS MOV #-1,R1 ; COUNT OF POWERS OF 2 15$: INC R1 ; COUNT THIS ONE ASR R0 ; SHIFT RIGHT BNE 15$ ; IF NE, COUNT ANOTHER POWER OF 2 ASL R1 ; ELSE, SHIFT C RNG LNG INTO POSITION ASL R1 ASL R1 MOVB R1,(R3) ; PUT IT IN WORD MOVB Q.RSPN(R2),R0 ; GET NUMBER OF RSP DESCRIPTORS MOV #-1,R1 ; COUNT POWERS OF 2 25$: INC R1 ; COUNT THIS ONE ASR R0 ; SHIFT RIGHT BNE 25$ ; IF NE, COUNT ANOTHER POWER OF 2 BISB R1,(R3) ; PUT IT IN WORD ALSO BISB #200,(R3) ; SET BIT 15 POP ; GET CST ; ; CONTINUE WITH INITIALIZATION AND START SYNCHRONIZATION ; CLR Q.SAD(R2) ; No steps are pending MOV #STEP1,Q.STEP(R2) ; Q.STEP=FIRST STEP VALUE EXPECTED CLR Q.INDX(R2) ; INITIALIZE OFFSET INTO TABLES TO ZERO MOV S.CSR(R4),R0 ; GET CSR ASSUME IP,0 CLR (R0) ; HARD INIT THE CONTROLLER PUSH <#500.> ; COUNTER FOR DELAY 30$: DEC (SP) ; COUNT DOWN BGT 30$ ; FOR ENTIRE DELAY TST (SP)+ ; CLEAN OFF STACK CALL WSW ; PROCESS START OF STEP 1 (TABLE DRIVEN) BCS OPN ; IN CASE OF ERROR GO TRY TO RE-TRY ; ; SET UP KS.EXT BIT IN K.STS FOR THE CONTROLLER, BASED ON QB BIT IN VALUE ; READ FROM SA AT THE START OF STEP 1 ; MOV S.KRB(R4),R4 ; GET THE KRB ADDRESS BIC #KS.EXT,K.STS(R4) ; ASSUME EXTENDED MEMORY NOT SUPPORTED BIT #QB,Q.TEMP(R2) ; CONTROLLER SUPPORT 22 BIT HOST BUS? BEQ 35$ ; IF EQ, NO ; ; * * * N O T E * * * ; ; THE FOLLOWING BRANCH MAY BE NOP'D IN ORDER TO ALLOW THE USE OF 22-BIT MSCP ; CONTROLLERS ON BUS ADAPTERS WHICH REQUIRE THE USE OF UNIBUS MAP REGISTERS. ; $$$BR1::BR 34$ ; NORMALLY SKIP THE SYSTEM CHECK BIT #HF.UBM,@HFMSK ; ARE THERE UMR'S ON THE SYSTEM BNE 35$ ; YES, THEN USE CONVERTER OPTION 34$: BIS #KS.EXT,K.STS(R4) ; INDICATE CONTROLLER IS ON 22 BIT BUS 35$: MOV U.SCB(R5),R4 ; RESTORE THE SCB ADDRESS PUSH <120000+SCUCB> ; GET ADDRESS OF THE SCAN UCB ROUTINE 37$: CALL @(SP)+ ; CALL THE COROUTINE BCS 45$ ; IF CS, ALL DONE BIC #DV.EXT,U.CW1(R5) ; ASSUME EXTENDED MEMORY NOT SUPPORTED BIT #QB,Q.TEMP(R2) ; CONTROLLER SUPPORT 22 BIT HOST BUS? BEQ 37$ ; IF EQ NO ; ; THE FOLLOWING BRANCH MAY BE NOP'D IN ORDER TO ALLOW THE USE OF 22-BIT MSCP ; CONTROLLERS ON BUS ADAPTERS WHICH REQUIRE THE USE OF UNIBUS MAP REGISTERS. ; $$$BR2::BR 38$ ; SKIP THE SYSTEM CHECKS BIT #HF.UBM,@HFMSK ; ARE THERE UMR'S ON THE SYSTEM BNE 37$ ; YES, THEN USE CONVERTER OPTION 38$: BIS #DV.EXT,U.CW1(R5) ; INDICATE DEVICE IS ON 22 BIT BUS BR 37$ ; GO DO ANOTHER 45$: ; CONTINUE ; ; SET UP THE RELOCATION REGISTERS AT UQRELQ ; CALL VACSET BCS BADSYN ; ERROR EXIT ; ; SET UP THE NEXT THREE WORDS TO SEND TO THE CONTROLLER ; PUSH ; SAVE CST MOV R2,R3 ; GET QST ADD #Q.WRIT+2,R3 ; GET TO ADDRESS OF THE NEXT START WORD MOV Q.RING(R2),R0 ; GET RING BASE ADDRESS CALL VACPA ; CONVERT TO PHYSICAL ADDRESS MOV R0,(R3)+ ; Q.WRIT+2=RING BASE LOW BITS MOV R1,(R3)+ ; Q.WRIT+4=RING BASE HIGH BITS MOV #LF!GO,(R3)+ ; Q.WRIT+6=LAST FAIL ! GO POP ; GET CST ; ; SET TIME-OUT AND RETURN. AN INTERRUPT WILL TRANSFER TO OPN2 TO PROCESS THE ; COMPLETION OF STEP 1 (BEGINNING OF STEP 2) ; MOVB #STMOC,S.ITM(R4) ; SET INITIAL TIMEOUT COUNT MOVB #STMOC,S.CTM(R4) ; AND CURRENT TIMEOUT COUNT MOV R5,S.BSYU(R4) ; SET THE BUSY UCB BISB #US.BSY,U.STS(R5) ; MARK THE UNIT AS BUSY MTPS #PR5 ; go to device priority TST Q.SAD(R2) ;;; any interrupts occur during setup BEQ 50$ ;;; If EQ, nope, finish up CALL OPN2 ;;; process the next step MTPS #PR0 ;;; return to priority 0 RETURN ; to caller 50$: MOV #OPN2,Q.SAD(R2) ;;; setup for next interrupt MTPS #PR0 ; return to priority 0 RETURN .DSABL LSB .PAGE .SBTTL . OPN2 ;+ ; AT THE START OF STEP 2 ; OPN2 IS JUMPED TO FROM UQINT (THE INTERRUPT PROCESSOR) ; ; INPUTS: ; ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R0-R1 = DESTROYED ; R2-R5 = PRESERVED ;- OPN2:: CALL WSW ; PROCESS STEP 2 (TABLE DRIVEN) BCC 5$ ; ALL IS OK JMP OPN ; WE FAILED, RESTART 5$: MOVB S.ITM(R4),S.CTM(R4) ; RESET CURRENT TIMEOUT COUNT MOV #OPN3,Q.SAD(R2) ; NEXT INTERRUPT WILL TAKE US TO OPN3 RETURN .PAGE .SBTTL . OPN3 ;+ ; AT THE START OF STEP 3 ; OPN3 IS JUMPED TO FROM UQINT (THE INTERRUPT PROCESSOR) ; ; INPUTS: ; ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; R0-R1 = DESTROYED ; R2-R5 = PRESERVED ;- OPN3:: CALL WSW ; PROCESS STEP 3 (TABLE DRIVEN) BCC 5$ ; SUCCESS JMP OPN ; FAILURE. GO RETRY 5$: MOVB S.ITM(R4),S.CTM(R4) ; RESET CURRENT TIMEOUT COUNT MOV #OPN4,Q.SAD(R2) ; NEXT INTERRUPT WILL TAKE US TO OPN4 RETURN .PAGE .SBTTL . OPN4 ;+ ; AT THE START OF STEP 4 ; OPN4 IS JUMPED TO FROM UQINT (THE INTERRUPT PROCESSOR) ; ; INPUTS: ; ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; R5 = UCB ADDRESS ; ; OUTPUTS: ; ; CONTROL IS TRANSFERED TO CLASYN ; C=0 (INDICATES SUCCESSFUL SYNCHRONIZATION) ; R0-R1 = DESTROYED ; R2-R5 = PRESERVED ;- OPN4:: CALL WSW ; PROCESS STEP 4 (TABLE DRIVEN) BCC 5$ ; IF CC, SUCCESS, CONTINUE JMP OPN ; ELSE JUMP TO OPN AND MAYBE RE-TRY 5$: CALL RNGSET ; SET UP RING DESCRIPTORS MOV #Q1.RDY,Q.STAT(R2) ; CONTROLLER STATE=READY MOV Q.FRSP(R2),Q.CRSP(R2) ; SET UP INITIAL RESPONSE RING POINTER MOV Q.FCMD(R2),Q.CCMD(R2) ; SET UP INITIAL COMMAND RING POINTER LOGSYN ; TRACE CONTROLLER INIT START CLC ; INDICATE SUCCESS JMPV CLASS,CLASYN ; TRANSFER TO CLASS DRIVER TO HANDLE .PAGE .SBTTL RNGSET - INITIAL SETUP OF RING DESCRIPTORS ;+ ; **-RNGSET-INITIAL SET UP OF RING DESCRIPTORS ; ; THIS ROUTINE IMPLEMENTS THE DESIGN DECISION TO STATICALLY ALLOCATE ; PACKET TO EACH RING DESCRIPTOR. IT FILLS IN EACH DESCRIPTOR WITH ; THE PHYSICAL ADDRESS OF THE PACKET ASSOCIATED WITH THE DESCRIPTOR. ; ; INPUTS: ; ; R2 = QST ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; ; R0-R1 = DESTROYED ;- RNGSET::PUSH ; SAVE R4,R3,R2, R2 MUST BE LAST! MOV Q.RING(R2),R3 ; GET RING BASE ADDRESS MOVB Q.RSPN(R2),R4 ; NUMBER OF RSP DESCR. MOV Q.RPAT(R2),R2 ; GET TABLE OF RSP PACKET ADDRESSES 5$: MOV (R2)+,R0 ; GET VA OF RSP PACKET (TEXT+0) MOV #RPLEN,MSGLNG(R0) ; SET MESSAGE LENGTH CLR CREDIT(R0) ; CLEAR CREDIT AND VCID CALL VACPA ; CONVERT VIRTUAL ADDR. TO PHYSICAL ; R0 = LOW BITS ; R1 = HIGH BITS MOV R0,(R3)+ ; FILL IN DESCR. WITH PHYSICAL PKT ADDR. MOV R1,(R3) ; THE WHOLE ADDRESS BIS #OWN!FLAG,(R3)+ ; DESCR. CONTROLLER OWNED AND REQUEST ; INTERRUPT ON RING TRANSITIONS SOB R4,5$ ; SET UP ALL RSP RING DESCRIPTORS MOV (SP),R2 ; GET QST MOVB Q.CMDN(R2),R4 ; GET # OF COMMAND DESCRIPTORS MOV Q.CPAT(R2),R2 ; GET TABLE OF CMD PACKET ADDRESS 10$: MOV (R2)+,R0 ; GET VA OF CMD PACKET (TEXT+0) MOV #CPLEN,MSGLNG(R0) ; SET MESSAGE LENGTH CLR CREDIT(R0) ; CLEAR CREDIT AND VCID CALL VACPA ; CONVERT VIRTUAL ADDR. TO PHYSICAL MOV R0,(R3)+ ; FILL IN DESCR. WITH PHYSICAL PKT ADDR. MOV R1,(R3)+ ; CMD PKTS ARE HOST OWNED SOB R4,10$ ; SET UP ALL CMD RING DESCRIPTORS POP ; RESTORE R2,R3,R4 RETURN .PAGE .SBTTL STOMP - BRING CONTROLLER TO THE OFFLINE STATE ;+ ; **-STOMP-CLOBBER THE CONTROLLER ; ; CALLED TO ENSURE THAT THE CONTROLLER IS IN AN OFFLINE STATE WHEN THE CLASS ; DRIVER DETERMINES THAT RESYNCH IS NECESSARY. ; ; INPUTS: ; ; R2 = QST ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; ; R0 = DESTROYED ; R2 = PRESERVED ; R4 = PRESERVED ;- STOMP: MOV S.CSR(R4),R0 ; GET CSR ASSUME IP,0 CLR (R0) ; STOMP THE CONTROLLER MOV #Q1.OFF,Q.STAT(R2) ; SET CONTROLLER STATE TO OFFLINE RETURN .PAGE .SBTTL VACPA - VIRTUAL TO PHYSICAL ADDRESS CONVERSION ;+ ; **-VACPA-VIRTUAL ADDRESS TO PHYSICAL ADDRESS CONVERSION ; ; CALLED TO CONVERT VIRTUAL PACKET ADDRESS TO PHYSICAL ADDRESS (OR UMR ADDRESS ; FOR AN EXTENDED MEMORY UNIBUS MACHINE). BECAUSE ALL PACKETS AND RINGS ARE IN ; SHARED COMMON MAPPED THROUGH APR 6 THE VIRTUAL ADDRESS MAY BE COMPUTED AS: ; ; (PHYSICAL ADDRESS)=(VIRTUAL ADDRESS)+(RELOCATION CONSTANT) ; ; SEE ROUTINE VACSET FOR DESCRIPTION OF HOW RELOCATION CONSTANT IS COMPUTED. ; ; INPUTS: ; ; R0 = VIRTUAL ADDRESS ; UQRELC=LOW BITS OF RELOCATION CONSTANT ; UQRELC+2=HIGH BITS OF RELOCATION CONSTANT ; ; OUTPUTS: ; ; R0 = LOW BITS OF PHYSICAL ADDRESS ; R1 = HIGH BITS OF PHYSICAL ADDRESS VACPA:: .IF DF,M$$PRO MOVB @PROC2,R1 ; get the processor index * 2 ASL R1 ; form a double word offset ADD UQRELC(R1),R0 ; R0 = low 16-bits of physical addr MOV UQRELC+2(R1),R1 ; ADC R1 ; R1 = high 16-bits of physical addr .IFF ;DF,M$$PRO CLR R1 ADD UQRELC,R0 ; R0 = LOW BITS OF PHYSICAL ADDRESS ADC R1 ADD UQRELC+2,R1 ; R1 = HIGH BITS OF PHYSICAL ADDRESS .ENDC ;DF,M$$PRO RETURN .PAGE .SBTTL VACSET - CALCULATE RELOCATION CONSTANT ;+ ; **-VACSET-CALCULATE RELOCATION CONSTANT ; ; THIS ROUTINE WILL CALCULATE THE RELOCATION CONSTANT NEEDED TO PERFORM VIRTUAL ; ADDRESS TO PHYSICAL ADDRESS CONVERSIONS (PA=VA+UQRELC). IF UMR IS NEEDED TO ; MAP UQCOM THIS ROUTINE WILL ALLOCATE AND MAP IT. ; ; INPUTS: ; ; R2 = QST ADDRESS ; R3 = CST ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; ; R0-R1 = DESTROYED ; R2-R5 = PRESERVED ; UQRELC AND UQRELC+2 ARE SET UP ; UQRELC HAS THE TWO HIGH BITS SET UP ; UQRELC+2 HAS THE 16 LOW BITS SET UP ; UMRS ARE MAPPED IF NECESSARY ;- VACSET::MOV @KISR6,R1 ; GET START OF PORT COMMON CLR R0 ; ZERO R0 ASHC #6.,R0 ; CALCULATE PHYSICAL ADDRESS MOV S.KRB(R4),R2 ; GET THE KRB ADDRESS BIT #KS.EXT,K.STS(R2) ; EXTENDED MEMORY SUPPORTED? BNE 50$ ; YES, DON'T GET UMR'S CLC ; TELL PORUMR IT'S ONLINE TRANSITION CALL PORUMR ; ALLOCATE/MAP UMR (GET WAIT BLOCKS TOO) BCS 60$ ; BAD, NO SPACE ALLOCATED 50$: SUB #140000,R1 ; SUBTRACT PORT COMMON VIRTUAL ADDRESS ; MAPPED THRU APR6 SBC R0 ; SUBTRACT CARRY FROM R0 .IF DF,M$$PRO MOVB @PROC2,R2 ; Get the processor index * 2 ASL R2 ; shift to * 4 MOV R1,UQRELC(R2) ; store the low order address MOV R0,UQRELC+2(R2) ; and the high order address .IFF ;DF,M$$PRO MOV R1,UQRELC ; LO ADDRESS MOV R0,UQRELC+2 ; HI .ENDC ;DF,M$$PRO MOV S.QST(R4),R2 ; GET QST ASSUME Q.CST,0 MOV (R2),R3 ; GET CST CLC ; GOOD RETURN 60$: RETURN .PAGE .SBTTL WSW - WAIT/RESPOND TO SYNCHRONIZATION STEP ;+ ; **-WSW-WAIT FOR AND RESPOND TO STEP IN THE HARDWARE SYNCHRONIZATION PROCESS ; ; WAIT UP TO 100 MICRO-SECONDS FOR STEP VALUE, READ AND SAVE SA, WRITE SA. ; ; INPUTS: ; ; R2 = QST ADDRESS ; R4 = SCB ADDRESS ; ; OUTPUTS: ; ; C=1 = ERROR DETECTED ; R0-R1 = DESTROYED ; ; C=0 = SUCCESS ; R0-R1 = DESTROYED ;- WSW:: MOV S.CSR(R4),R1 ; GET CSR CLR R0 ; LOOP CONTROL 5$: TST SA(R1) ; CONTROLLER ERROR OCCURRED? BMI 15$ ; YES. RETURN BIT Q.STEP(R2),SA(R1) ; DESIRED STEP BIT SET? BNE 10$ ; YES. SUCCESS SOB R0,5$ ; WAIT UP TO 100 MICRO-SEC. FOR STEP BIT BR 15$ ; TIME IS UP, GO SET CARRY AND RETURN ; ; STEP HAS COMPLETED AND THE NEXT STEP HAS BEGUN ; 10$: MOV Q.INDX(R2),R0 ; INDEX INTO Q.WRIT TABLE ADD R2,R0 ; GET ACTUAL TABLE ADDRESS MOV SA(R1),Q.TEMP(R2) ; READ/SAVE SA REGISTER TEMPORARILY LOGSTP ; TRACE CONTROLLER INIT STEP MOV Q.WRIT(R0),SA(R1) ; WRITE TO SA FROM Q.WRIT TABLE ASL Q.STEP(R2) ; UPDATE Q.STEP AND ADD #2,Q.INDX(R2) ; Q.INDX CLC ; INDICATE SUCCESS BR 20$ ; GO TO RETURN 15$: SEC ; INDICATE ERROR DETECTED 20$: RETURN LOGRTN ; TRACE ROUTINES CODLEN = <.-CODBEG>/2 ; LENGTH OF CODE SECTION IN WORDS .END